package org.zheng.shop.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.zheng.shop.dto.CompanyNewsDTO;
import org.zheng.shop.entity.CompanyNews;
import org.zheng.shop.entity.User;
import org.zheng.shop.repository.CompanyNewsRepository;
import org.zheng.shop.repository.UserRepository;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 企业动态服务
 */
@Service
@Transactional
public class CompanyNewsService {

    @Autowired
    private CompanyNewsRepository newsRepository;

    @Autowired
    private UserRepository userRepository;

    /**
     * 获取可见的动态列表（分页）
     */
    public Page<CompanyNewsDTO> getVisibleNews(int page, int size) {
        Pageable pageable = PageRequest.of(page, size);
        Page<CompanyNews> newsPage = newsRepository.findVisibleNews(pageable);
        return newsPage.map(CompanyNewsDTO::new);
    }

    /**
     * 获取所有动态列表（管理员，分页）
     */
    public Page<CompanyNewsDTO> getAllNews(int page, int size) {
        Pageable pageable = PageRequest.of(page, size);
        Page<CompanyNews> newsPage = newsRepository.findAllByOrderByCreatedAtDesc(pageable);
        return newsPage.map(CompanyNewsDTO::new);
    }

    /**
     * 根据ID获取动态详情
     */
    public CompanyNewsDTO getNewsById(Long id, boolean isAdmin) {
        Optional<CompanyNews> newsOpt = newsRepository.findById(id);
        if (newsOpt.isEmpty()) {
            throw new RuntimeException("动态不存在");
        }

        CompanyNews news = newsOpt.get();
        
        // 如果不是管理员，检查是否可见
        if (!isAdmin && !news.getIsVisible()) {
            throw new RuntimeException("动态不存在或不可见");
        }

        return new CompanyNewsDTO(news);
    }

    /**
     * 增加浏览次数
     */
    @Transactional
    public void incrementViewCount(Long id) {
        newsRepository.incrementViewCount(id);
    }

    /**
     * 创建动态
     */
    public CompanyNewsDTO createNews(CompanyNewsDTO newsDTO, Integer authorId) {
        // 获取作者信息
        Optional<User> authorOpt = userRepository.findById(authorId);
        if (authorOpt.isEmpty()) {
            throw new RuntimeException("作者不存在");
        }

        User author = authorOpt.get();
        
        CompanyNews news = new CompanyNews();
        news.setTitle(newsDTO.getTitle());
        news.setContent(newsDTO.getContent());
        news.setSummary(newsDTO.getSummary());
        news.setCoverImage(newsDTO.getCoverImage());
        news.setIsVisible(newsDTO.getIsVisible() != null ? newsDTO.getIsVisible() : true);
        news.setIsPinned(newsDTO.getIsPinned() != null ? newsDTO.getIsPinned() : false);
        news.setAuthorId(authorId);
        news.setAuthorName(author.getUsername());
        news.setCreatedAt(LocalDateTime.now());
        news.setUpdatedAt(LocalDateTime.now());
        news.setPublishedAt(LocalDateTime.now());
        news.setViewCount(0);

        news = newsRepository.save(news);
        return new CompanyNewsDTO(news);
    }

    /**
     * 更新动态
     */
    public CompanyNewsDTO updateNews(Long id, CompanyNewsDTO newsDTO, Integer authorId) {
        Optional<CompanyNews> newsOpt = newsRepository.findById(id);
        if (newsOpt.isEmpty()) {
            throw new RuntimeException("动态不存在");
        }

        CompanyNews news = newsOpt.get();
        
        // 检查权限（只有作者或管理员可以编辑）
        Optional<User> userOpt = userRepository.findById(authorId);
        if (userOpt.isEmpty()) {
            throw new RuntimeException("用户不存在");
        }
        
        User user = userOpt.get();
        if (!user.getIsAdmin() && !news.getAuthorId().equals(authorId)) {
            throw new RuntimeException("无权限编辑此动态");
        }

        // 更新字段
        news.setTitle(newsDTO.getTitle());
        news.setContent(newsDTO.getContent());
        news.setSummary(newsDTO.getSummary());
        news.setCoverImage(newsDTO.getCoverImage());
        news.setIsVisible(newsDTO.getIsVisible() != null ? newsDTO.getIsVisible() : news.getIsVisible());
        news.setIsPinned(newsDTO.getIsPinned() != null ? newsDTO.getIsPinned() : news.getIsPinned());
        news.setUpdatedAt(LocalDateTime.now());

        news = newsRepository.save(news);
        return new CompanyNewsDTO(news);
    }

    /**
     * 删除动态
     */
    public void deleteNews(Long id, Integer userId) {
        Optional<CompanyNews> newsOpt = newsRepository.findById(id);
        if (newsOpt.isEmpty()) {
            throw new RuntimeException("动态不存在");
        }

        CompanyNews news = newsOpt.get();
        
        // 检查权限（只有作者或管理员可以删除）
        Optional<User> userOpt = userRepository.findById(userId);
        if (userOpt.isEmpty()) {
            throw new RuntimeException("用户不存在");
        }
        
        User user = userOpt.get();
        if (!user.getIsAdmin() && !news.getAuthorId().equals(userId)) {
            throw new RuntimeException("无权限删除此动态");
        }

        newsRepository.delete(news);
    }

    /**
     * 切换动态可见性
     */
    public CompanyNewsDTO toggleVisibility(Long id, Integer userId) {
        Optional<CompanyNews> newsOpt = newsRepository.findById(id);
        if (newsOpt.isEmpty()) {
            throw new RuntimeException("动态不存在");
        }

        CompanyNews news = newsOpt.get();
        
        // 检查权限
        Optional<User> userOpt = userRepository.findById(userId);
        if (userOpt.isEmpty()) {
            throw new RuntimeException("用户不存在");
        }
        
        User user = userOpt.get();
        if (!user.getIsAdmin() && !news.getAuthorId().equals(userId)) {
            throw new RuntimeException("无权限修改此动态");
        }

        news.setIsVisible(!news.getIsVisible());
        news.setUpdatedAt(LocalDateTime.now());
        
        news = newsRepository.save(news);
        return new CompanyNewsDTO(news);
    }

    /**
     * 切换置顶状态
     */
    public CompanyNewsDTO togglePin(Long id, Integer userId) {
        Optional<CompanyNews> newsOpt = newsRepository.findById(id);
        if (newsOpt.isEmpty()) {
            throw new RuntimeException("动态不存在");
        }

        CompanyNews news = newsOpt.get();
        
        // 只有管理员可以置顶
        Optional<User> userOpt = userRepository.findById(userId);
        if (userOpt.isEmpty() || !userOpt.get().getIsAdmin()) {
            throw new RuntimeException("无权限置顶动态");
        }

        news.setIsPinned(!news.getIsPinned());
        news.setUpdatedAt(LocalDateTime.now());
        
        news = newsRepository.save(news);
        return new CompanyNewsDTO(news);
    }

    /**
     * 搜索动态
     */
    public Page<CompanyNewsDTO> searchNews(String keyword, int page, int size, boolean isAdmin) {
        Pageable pageable = PageRequest.of(page, size);
        Page<CompanyNews> newsPage;
        
        if (isAdmin) {
            newsPage = newsRepository.searchAllNewsByTitle(keyword, pageable);
        } else {
            newsPage = newsRepository.searchVisibleNewsByTitle(keyword, pageable);
        }
        
        return newsPage.map(CompanyNewsDTO::new);
    }

    /**
     * 获取最新的几条动态
     */
    public List<CompanyNewsDTO> getLatestNews(int limit) {
        Pageable pageable = PageRequest.of(0, limit);
        List<CompanyNews> newsList = newsRepository.findLatestVisibleNews(pageable);
        return newsList.stream().map(CompanyNewsDTO::new).collect(Collectors.toList());
    }

    /**
     * 获取置顶动态
     */
    public List<CompanyNewsDTO> getPinnedNews() {
        List<CompanyNews> newsList = newsRepository.findPinnedVisibleNews();
        return newsList.stream().map(CompanyNewsDTO::new).collect(Collectors.toList());
    }
}
